using AutoMapper;
using SqlSugar;
using SqlsugarService.Application.DTOs.Common;
using SqlsugarService.Application.DTOs.WorkOrderTaskDto;
using SqlsugarService.Application.IService.Plan;
using SqlsugarService.Application.Until;
using SqlsugarService.Domain.Plan;
using SqlsugarService.Domain.QualityInspection;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;

namespace SqlsugarService.Application.Service.Plan
{
    /// <summary>
    /// 工单任务服务实现
    /// </summary>
    public class WorkOrderTaskService : IWorkOrderTaskService
    {
        private readonly ISqlSugarClient _db;
        private readonly IMapper _mapper;

        public WorkOrderTaskService(ISqlSugarClient db, IMapper mapper)
        {
            _db = db;
            _mapper = mapper;
        }

        /// <summary>
        /// 获取工单任务分页列表
        /// </summary>
        public async Task<ApiResult<PageResult<List<GetWorkOrderTaskDto>>>> GetWorkOrderTaskListAsync(GetWorkOrderTaskSearchDto searchDto)
        {
            try
            {
                // 添加调试日志
                Console.WriteLine($"搜索条件 - TaskNumber: {searchDto.TaskNumber}, TaskName: {searchDto.TaskName}");
                Console.WriteLine($"搜索条件 - ProductionOrderId: {searchDto.ProductionOrderId}");
                Console.WriteLine($"搜索条件 - Status: {searchDto.Status}, Priority: {searchDto.Priority}");
                Console.WriteLine($"搜索条件 - PlanStartTimeBegin: {searchDto.PlanStartTimeBegin}, PlanStartTimeEnd: {searchDto.PlanStartTimeEnd}");

                // 先构建基础查询，不使用 JOIN 避免数据关联问题
                var query = _db.Queryable<WorkOrderTaskEntity>();

                // 只添加非空的搜索条件
                if (!string.IsNullOrEmpty(searchDto.TaskNumber))
                {
                    query = query.Where(x => x.TaskNumber.Contains(searchDto.TaskNumber));
                    Console.WriteLine($"添加TaskNumber条件: {searchDto.TaskNumber}");
                }

                if (!string.IsNullOrEmpty(searchDto.TaskName))
                {
                    query = query.Where(x => x.TaskName.Contains(searchDto.TaskName));
                    Console.WriteLine($"添加TaskName条件: {searchDto.TaskName}");
                }

                if (searchDto.ProductionOrderId.HasValue)
                {
                    query = query.Where(x => x.ProductionOrderId == searchDto.ProductionOrderId.Value);
                    Console.WriteLine($"添加ProductionOrderId条件: {searchDto.ProductionOrderId}");
                }

                if (!string.IsNullOrEmpty(searchDto.StationName))
                {
                    query = query.Where(x => x.StationName.Contains(searchDto.StationName));
                    Console.WriteLine($"添加StationName条件: {searchDto.StationName}");
                }

                if (!string.IsNullOrEmpty(searchDto.ProcessCode))
                {
                    query = query.Where(x => x.ProcessCode.Contains(searchDto.ProcessCode));
                    Console.WriteLine($"添加ProcessCode条件: {searchDto.ProcessCode}");
                }

                if (!string.IsNullOrEmpty(searchDto.ProcessName))
                {
                    query = query.Where(x => x.ProcessName.Contains(searchDto.ProcessName));
                    Console.WriteLine($"添加ProcessName条件: {searchDto.ProcessName}");
                }

                if (!string.IsNullOrEmpty(searchDto.Status))
                {
                    query = query.Where(x => x.Status == searchDto.Status);
                    Console.WriteLine($"添加Status条件: {searchDto.Status}");
                }

                if (searchDto.Priority.HasValue)
                {
                    query = query.Where(x => x.Priority == searchDto.Priority.Value);
                    Console.WriteLine($"添加Priority条件: {searchDto.Priority}");
                }

                // 时间条件需要特别注意
                if (searchDto.PlanStartTimeBegin.HasValue)
                {
                    query = query.Where(x => x.PlanStartTime >= searchDto.PlanStartTimeBegin.Value);
                    Console.WriteLine($"添加PlanStartTimeBegin条件: {searchDto.PlanStartTimeBegin}");
                }

                if (searchDto.PlanStartTimeEnd.HasValue)
                {
                    query = query.Where(x => x.PlanStartTime <= searchDto.PlanStartTimeEnd.Value);
                    Console.WriteLine($"添加PlanStartTimeEnd条件: {searchDto.PlanStartTimeEnd}");
                }

                if (searchDto.PlanEndTimeBegin.HasValue)
                {
                    query = query.Where(x => x.PlanEndTime >= searchDto.PlanEndTimeBegin.Value);
                    Console.WriteLine($"添加PlanEndTimeBegin条件: {searchDto.PlanEndTimeBegin}");
                }

                if (searchDto.PlanEndTimeEnd.HasValue)
                {
                    query = query.Where(x => x.PlanEndTime <= searchDto.PlanEndTimeEnd.Value);
                    Console.WriteLine($"添加PlanEndTimeEnd条件: {searchDto.PlanEndTimeEnd}");
                }

                var totalCount = await query.CountAsync();
                Console.WriteLine($"查询结果总数: {totalCount}");

                var entities = await query
                    .OrderByDescending(x => x.CreatedAt)
                    .Select(x => new GetWorkOrderTaskDto
                    {
                        Id = x.Id,
                        SequenceNumber = x.SequenceNumber,
                        TaskNumber = x.TaskNumber,
                        TaskName = x.TaskName,
                        ProductionOrderId = x.ProductionOrderId,
                        ProductionOrderNumber = "", // 暂时不关联生产工单，避免JOIN问题
                        StationName = x.StationName,
                        ProcessCode = x.ProcessCode,
                        ProcessName = x.ProcessName,
                        ProcessFlow = x.ProcessFlow,
                        ProcessType = x.ProcessType,
                        TaskColor = x.TaskColor,
                        PlanQuantity = x.PlanQuantity,
                        ActualQuantity = x.ActualQuantity,
                        PlanStartTime = x.PlanStartTime,
                        PlanEndTime = x.PlanEndTime,
                        ActualStartTime = x.ActualStartTime,
                        ActualEndTime = x.ActualEndTime,
                        PlanDuration = x.PlanDuration,
                        ActualDuration = x.ActualDuration,
                        Status = x.Status,
                        ProcessRouteId = x.ProcessRouteId,
                        ProcessStepId = x.ProcessStepId,
                        Priority = x.Priority,
                        Remarks = x.Remarks,
                        CreateTime = x.CreatedAt,
                        UpdateTime = x.UpdatedAt
                    })
                    .ToPageListAsync(searchDto.PageIndex, searchDto.PageSize);

                var pageResult = new PageResult<List<GetWorkOrderTaskDto>>
                {
                    Items = entities,
                    TotalCount = totalCount,
                    TotalPage = (int)Math.Ceiling(totalCount * 1.0 / searchDto.PageSize),
                    PageIndex = searchDto.PageIndex,
                    PageSize = searchDto.PageSize
                };

                return ApiResult<PageResult<List<GetWorkOrderTaskDto>>>.Success(pageResult, ResultCode.Success);
            }
            catch (Exception ex)
            {
                return ApiResult<PageResult<List<GetWorkOrderTaskDto>>>.Fail($"获取工单任务列表失败：{ex.Message}", ResultCode.Error);
            }
        }

        /// <summary>
        /// 根据ID获取工单任务详情
        /// </summary>
        public async Task<ApiResult<GetWorkOrderTaskDto>> GetWorkOrderTaskByIdAsync(Guid id)
        {
            try
            {
                var entity = await _db.Queryable<WorkOrderTaskEntity>()
                    .LeftJoin<ProductionOrder>((wot, po) => wot.ProductionOrderId == po.Id)
                    .Where((wot, po) => wot.Id == id)
                    .Select((wot, po) => new GetWorkOrderTaskDto
                    {
                        Id = wot.Id,
                        SequenceNumber = wot.SequenceNumber,
                        TaskNumber = wot.TaskNumber,
                        TaskName = wot.TaskName,
                        ProductionOrderId = wot.ProductionOrderId,
                        ProductionOrderNumber = po.OrderNumber,
                        StationName = wot.StationName,
                        ProcessCode = wot.ProcessCode,
                        ProcessName = wot.ProcessName,
                        ProcessFlow = wot.ProcessFlow,
                        ProcessType = wot.ProcessType,
                        TaskColor = wot.TaskColor,
                        PlanQuantity = wot.PlanQuantity,
                        ActualQuantity = wot.ActualQuantity,
                        PlanStartTime = wot.PlanStartTime,
                        PlanEndTime = wot.PlanEndTime,
                        ActualStartTime = wot.ActualStartTime,
                        ActualEndTime = wot.ActualEndTime,
                        PlanDuration = wot.PlanDuration,
                        ActualDuration = wot.ActualDuration,
                        Status = wot.Status,
                        ProcessRouteId = wot.ProcessRouteId,
                        ProcessStepId = wot.ProcessStepId,
                        Priority = wot.Priority,
                        Remarks = wot.Remarks,
                        CreateTime = wot.CreatedAt,
                        UpdateTime = wot.UpdatedAt
                    })
                    .FirstAsync();

                if (entity == null)
                {
                    return ApiResult<GetWorkOrderTaskDto>.Fail("工单任务不存在", ResultCode.NotFound);
                }

                return ApiResult<GetWorkOrderTaskDto>.Success(entity, ResultCode.Success);
            }
            catch (Exception ex)
            {
                return ApiResult<GetWorkOrderTaskDto>.Fail($"获取工单任务详情失败：{ex.Message}", ResultCode.Error);
            }
        }

        /// <summary>
        /// 工单任务报工
        /// </summary>
        public async Task<ApiResult> WorkReportAsync(WorkReportDto workReportDto)
        {
            try
            {
                await _db.Ado.BeginTranAsync();

                try
                {
                    var result = await ProcessWorkReportAsync(workReportDto);
                    if (!result.IsSuc)
                    {
                        await _db.Ado.RollbackTranAsync();
                        return result;
                    }

                    await _db.Ado.CommitTranAsync();
                    return ApiResult.Success(ResultCode.Success);
                }
                catch (Exception)
                {
                    await _db.Ado.RollbackTranAsync();
                    throw;
                }
            }
            catch (Exception ex)
            {
                return ApiResult.Fail($"报工失败：{ex.Message}", ResultCode.Error);
            }
        }

        /// <summary>
        /// 处理报工逻辑（内部方法，不包含事务）
        /// </summary>
        private async Task<ApiResult> ProcessWorkReportAsync(WorkReportDto workReportDto)
        {
            try
            {
                // 1. 验证工单任务是否存在
                var workOrderTask = await _db.Queryable<WorkOrderTaskEntity>()
                    .FirstAsync(x => x.Id == workReportDto.WorkOrderTaskId);

                if (workOrderTask == null)
                {
                    return ApiResult.Fail("工单任务不存在", ResultCode.NotFound);
                }

                // 2. 生成检验单号
                var inspectionCode = await GenerateInspectionCodeAsync();

                // 3. 创建报工质检记录
                var workReportInspection = new WorkReportInspectionEntity
                {
                    Id = Guid.NewGuid(),
                    InspectionCode = inspectionCode,
                    InspectionName = workReportDto.InspectionName,
                    InspectionType = workReportDto.InspectionType,
                    Status = "待检验", // 默认状态
                    ProductId = workReportDto.ProductId ?? Guid.Empty,
                    ProcessStepId = workReportDto.ProcessStepId ?? workOrderTask.ProcessStepId ?? Guid.Empty,
                    StationId = workReportDto.StationId ?? Guid.Empty,
                    TeamId = workReportDto.TeamId ?? Guid.Empty,
                    ReporterId = workReportDto.ReporterId,
                    InspectorId = workReportDto.InspectorId ?? Guid.Empty,
                    ReportedQuantity = workReportDto.ReportedQuantity,
                    ReportTime = workReportDto.ReportTime,
                    InspectionTime = workReportDto.InspectionTime,
                    InspectionDepartment = workReportDto.InspectionDepartment ?? string.Empty,
                    TestedQuantity = workReportDto.TestedQuantity,
                    QualifiedQuantity = workReportDto.QualifiedQuantity,
                    UnqualifiedQuantity = workReportDto.UnqualifiedQuantity,
                    OverallResult = workReportDto.OverallResult ?? string.Empty,
                    Remark = workReportDto.Remark ?? string.Empty,
                    CreatedAt = DateTime.Now,
                    UpdatedAt = DateTime.Now
                };

                // 4. 插入报工质检记录
                await _db.Insertable(workReportInspection).ExecuteCommandAsync();

                // 5. 更新工单任务的实际数量
                workOrderTask.ActualQuantity += workReportDto.ReportedQuantity;
                workOrderTask.UpdatedAt = DateTime.Now;

                // 如果是第一次报工，设置实际开工时间
                if (workOrderTask.ActualStartTime == null)
                {
                    workOrderTask.ActualStartTime = workReportDto.ReportTime;
                    workOrderTask.Status = "进行中";
                }

                // 如果实际数量达到计划数量，设置完工时间和状态
                if (workOrderTask.ActualQuantity >= workOrderTask.PlanQuantity)
                {
                    workOrderTask.ActualEndTime = workReportDto.ReportTime;
                    workOrderTask.Status = "已报工";

                    // 计算实际用时
                    if (workOrderTask.ActualStartTime.HasValue)
                    {
                        var duration = workReportDto.ReportTime - workOrderTask.ActualStartTime.Value;
                        workOrderTask.ActualDuration = (decimal)duration.TotalHours;
                    }
                }

                await _db.Updateable(workOrderTask).ExecuteCommandAsync();

                return ApiResult.Success(ResultCode.Success);
            }
            catch (Exception ex)
            {
                return ApiResult.Fail($"处理报工失败：{ex.Message}", ResultCode.Error);
            }
        }

        /// <summary>
        /// 批量工单任务报工
        /// </summary>
        public async Task<ApiResult> BatchWorkReportAsync(List<WorkReportDto> workReportDtos)
        {
            try
            {
                await _db.Ado.BeginTranAsync();

                try
                {
                    foreach (var workReportDto in workReportDtos)
                    {
                        // 直接调用内部报工逻辑，避免嵌套事务
                        var result = await ProcessWorkReportAsync(workReportDto);
                        if (!result.IsSuc)
                        {
                            await _db.Ado.RollbackTranAsync();
                            return result;
                        }
                    }

                    await _db.Ado.CommitTranAsync();
                    return ApiResult.Success(ResultCode.Success);
                }
                catch (Exception)
                {
                    await _db.Ado.RollbackTranAsync();
                    throw;
                }
            }
            catch (Exception ex)
            {
                return ApiResult.Fail($"批量报工失败：{ex.Message}", ResultCode.Error);
            }
        }

        /// <summary>
        /// 获取工单任务的报工记录
        /// </summary>
        public async Task<ApiResult<List<object>>> GetWorkReportsByTaskIdAsync(Guid workOrderTaskId)
        {
            try
            {
                // 这里需要通过工单任务关联到报工记录
                // 由于报工质检表没有直接关联工单任务ID，我们可以通过其他字段关联
                // 或者需要在报工质检表中添加工单任务ID字段

                var reports = await _db.Queryable<WorkReportInspectionEntity>()
                    .Where(x => x.CreatedAt >= DateTime.Today.AddDays(-30)) // 临时查询最近30天的记录
                    .Select(x => new
                    {
                        x.Id,
                        x.InspectionCode,
                        x.InspectionName,
                        x.InspectionType,
                        x.Status,
                        x.ReportedQuantity,
                        x.ReportTime,
                        x.InspectionTime,
                        x.QualifiedQuantity,
                        x.UnqualifiedQuantity,
                        x.OverallResult,
                        x.Remark
                    })
                    .ToListAsync();

                return ApiResult<List<object>>.Success(reports.Cast<object>().ToList(), ResultCode.Success);
            }
            catch (Exception ex)
            {
                return ApiResult<List<object>>.Fail($"获取报工记录失败：{ex.Message}", ResultCode.Error);
            }
        }

        /// <summary>
        /// 生成检验单号
        /// </summary>
        private async Task<string> GenerateInspectionCodeAsync()
        {
            var today = DateTime.Today;
            var prefix = $"QC{today:yyyyMMdd}";

            var maxCode = await _db.Queryable<WorkReportInspectionEntity>()
                .Where(x => x.InspectionCode.StartsWith(prefix))
                .MaxAsync(x => x.InspectionCode);

            if (string.IsNullOrEmpty(maxCode))
            {
                return $"{prefix}001";
            }

            var numberPart = maxCode.Substring(prefix.Length);
            if (int.TryParse(numberPart, out int number))
            {
                return $"{prefix}{(number + 1):D3}";
            }

            return $"{prefix}001";
        }

        /// <summary>
        /// 获取所有工单任务（用于调试）
        /// </summary>
        public async Task<ApiResult<List<GetWorkOrderTaskDto>>> GetAllWorkOrderTasksAsync()
        {
            try
            {
                // 先尝试不使用 JOIN 查询，直接查询工单任务表
                var entities = await _db.Queryable<WorkOrderTaskEntity>()
                    .OrderByDescending(x => x.CreatedAt)
                    .Select(x => new GetWorkOrderTaskDto
                    {
                        Id = x.Id,
                        SequenceNumber = x.SequenceNumber,
                        TaskNumber = x.TaskNumber,
                        TaskName = x.TaskName,
                        ProductionOrderId = x.ProductionOrderId,
                        ProductionOrderNumber = "", // 暂时不关联
                        StationName = x.StationName,
                        ProcessCode = x.ProcessCode,
                        ProcessName = x.ProcessName,
                        ProcessFlow = x.ProcessFlow,
                        ProcessType = x.ProcessType,
                        TaskColor = x.TaskColor,
                        PlanQuantity = x.PlanQuantity,
                        ActualQuantity = x.ActualQuantity,
                        PlanStartTime = x.PlanStartTime,
                        PlanEndTime = x.PlanEndTime,
                        ActualStartTime = x.ActualStartTime,
                        ActualEndTime = x.ActualEndTime,
                        PlanDuration = x.PlanDuration,
                        ActualDuration = x.ActualDuration,
                        Status = x.Status,
                        ProcessRouteId = x.ProcessRouteId,
                        ProcessStepId = x.ProcessStepId,
                        Priority = x.Priority,
                        Remarks = x.Remarks,
                        CreateTime = x.CreatedAt,
                        UpdateTime = x.UpdatedAt
                    })
                    .ToListAsync();

                return ApiResult<List<GetWorkOrderTaskDto>>.Success(entities, ResultCode.Success);
            }
            catch (Exception ex)
            {
                return ApiResult<List<GetWorkOrderTaskDto>>.Fail($"获取所有工单任务失败：{ex.Message}", ResultCode.Error);
            }
        }

        /// <summary>
        /// 批量派工（支持单个和批量）
        /// </summary>
        public async Task<ApiResult> BatchDispatchWorkAsync(List<DispatchWorkDto> dispatchWorkDtos)
        {
            try
            {
                if (dispatchWorkDtos == null || !dispatchWorkDtos.Any())
                {
                    return ApiResult.Fail("派工信息不能为空", ResultCode.ValidationError);
                }

                await _db.Ado.BeginTranAsync();

                try
                {
                    var dispatchWorkEntities = new List<Dispatchwork>();
                    var workOrderTasksToUpdate = new List<WorkOrderTaskEntity>();

                    foreach (var dto in dispatchWorkDtos)
                    {
                        // 验证工单任务是否存在
                        var workOrderTask = await _db.Queryable<WorkOrderTaskEntity>()
                            .FirstAsync(x => x.Id == dto.WorkOrderTaskEntityId);

                        if (workOrderTask == null)
                        {
                            await _db.Ado.RollbackTranAsync();
                            return ApiResult.Fail($"工单任务ID {dto.WorkOrderTaskEntityId} 不存在", ResultCode.NotFound);
                        }

                        // 检查是否已经派工
                        var existingDispatch = await _db.Queryable<Dispatchwork>()
                            .FirstAsync(x => x.WorkOrderTaskEntityId == dto.WorkOrderTaskEntityId);

                        if (existingDispatch != null)
                        {
                            await _db.Ado.RollbackTranAsync();
                            return ApiResult.Fail($"工单任务 {workOrderTask.TaskName} 已经派工，不能重复派工", ResultCode.AlreadyExists);
                        }

                        // 创建派工实体
                        var dispatchWork = new Dispatchwork
                        {
                            Id = Guid.NewGuid(),
                            WorkOrderTaskEntityId = dto.WorkOrderTaskEntityId,
                            TeamName = dto.TeamName,
                            Teamprincipal = dto.Teamprincipal,
                            OtherMembers = dto.OtherMembers,
                            QualityTestingDept = dto.QualityTestingDept,
                            QualityTestingPeople = dto.QualityTestingPeople,
                            Descr = dto.Descr,
                            CreatedAt = DateTime.Now,
                            UpdatedAt = DateTime.Now
                        };

                        dispatchWorkEntities.Add(dispatchWork);

                        // 更新工单任务状态为"已派工"
                        workOrderTask.Status = "已派工";
                        workOrderTask.UpdatedAt = DateTime.Now;
                        workOrderTasksToUpdate.Add(workOrderTask);
                    }

                    // 批量插入派工记录
                    await _db.Insertable(dispatchWorkEntities).ExecuteCommandAsync();

                    // 批量更新工单任务状态
                    await _db.Updateable(workOrderTasksToUpdate).ExecuteCommandAsync();

                    await _db.Ado.CommitTranAsync();
                    return ApiResult.Success(ResultCode.Success);
                }
                catch (Exception)
                {
                    await _db.Ado.RollbackTranAsync();
                    throw;
                }
            }
            catch (Exception ex)
            {
                return ApiResult.Fail($"派工失败：{ex.Message}", ResultCode.Error);
            }
        }
    }
}
